package edu.gettysburg.catapp1;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;

import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import android.widget.LinearLayout.LayoutParams;
import android.support.v4.app.NavUtils;

public class InitialSite extends Activity {
	private VideoView audioView;
	private Uri audioURI;
	private MediaController mc;
	private String mCurrentPhotoPath;
	private static final String JPEG_FILE_PREFIX = "IMG_";
	private static final String JPEG_FILE_SUFFIX = ".jpg";
	private static final int ACTION_TAKE_PHOTO = 1;

	public static int SITE_NUM = 1;

	/*
	 * (non-Javadoc)
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 * 
	 * This generates the site page dynamically. It includes:
	 * - hide of action bar
	 * - general navigation bar
	 * - description of site
	 * - scrollable list of media on the right side
	 */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentBasedOnLayout();


		//Recalls saved instance of audio before onDestroy() was called [during orientation change, etc.]
		if(savedInstanceState != null) {
			if(savedInstanceState.get("uriPath") != null) {
				int pos = savedInstanceState.getInt("pos");

				audioURI = Uri.parse((String) savedInstanceState.get("uriPath"));
				audioView =  (VideoView) findViewById(R.id.audioHandle);
				mc = new MediaController(this);
				mc.setAnchorView(audioView);
				audioView.setVideoURI(audioURI);
				audioView.setMediaController(mc);
				audioView.seekTo(pos);
				if(savedInstanceState.getBoolean("play")) {
					audioView.start();
				}
			}
			else {
				audioView =  (VideoView) findViewById(R.id.audioHandle);
				mc = new MediaController(this);
				mc.setAnchorView(audioView);
			}
		}
		else {
			audioView =  (VideoView) findViewById(R.id.audioHandle);
			mc = new MediaController(this);
			mc.setAnchorView(audioView);
		}

		final int numSites = refreshViews();

		getActionBar().hide();

		final Button b1 = (Button) findViewById(R.id.btn1);
		final Button b2 = (Button) findViewById(R.id.btn2);
		final Button b3 = (Button) findViewById(R.id.btn3);
		final Button b4 = (Button) findViewById(R.id.btn4);
		final Button b5 = (Button) findViewById(R.id.btn5);

		//Takes user to the previous page
		b1.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				onBackPressed();
			}
		});

		//Takes user to the next stage of the tour
		b2.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if(audioView != null) {
					audioView.stopPlayback();
				}
				if(SITE_NUM == TourOverview.TOUR_OBJECT.getSites().size()) {
					Intent intent = new Intent(getBaseContext(), TourRecap.class);
					startActivity(intent);
				}
				else {
					Intent intent = new Intent(getBaseContext(), ViewMap.class);
					startActivity(intent);
				}
			}
		});

		//Allows user to control audio
		b3.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if(audioView != null) {
					mc.show();
				}
			}
		});

		//Takes user to view the map
		b4.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent intent = new Intent(getBaseContext(), ViewMap.class);
				startActivity(intent);
			}
		});

		//Takes user to camera app, saves photo upon return
		b5.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
				File _file = null;
				try {
					_file = createImageFile();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(_file));
				galleryAddPic();
				startActivityForResult(intent, ACTION_TAKE_PHOTO);
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 * 
	 * Overridden method: Not used because the action bar is hidden
	 */
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.initial_site, menu);
		return true;
	}

	/*
	 * (non-Javadoc)
	 * @see android.app.Activity#onBackPressed()
	 * Slight variation: if it is not the first site, it decreases the count of the current site
	 */
	public void onBackPressed() {
		if(SITE_NUM > 1) {
			SITE_NUM--;
			super.onBackPressed();
		}
		else {
			super.onBackPressed();
		}
	}

	/*
	 * (non-Javadoc)
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 * 
	 * Overridden method: Not used because the action bar is hidden
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			NavUtils.navigateUpFromSameTask(this);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/*
	 * (non-Javadoc)
	 * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
	 * 
	 * Saves instance of important objects on site page:
	 * - audioURI
	 * - position of audio
	 * - state of audio
	 */
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if(audioView != null) {
			outState.putInt("pos", audioView.getCurrentPosition());
			if(audioURI != null) {
				outState.putString("uriPath", audioURI.getEncodedPath());
			}
			if(audioView.isPlaying()) {
				boolean play = true;
				outState.putBoolean("play", play);
			}
			else {
				boolean play = false;
				outState.putBoolean("play", play);
			}
		}
	}

	/**
	 * Returns the directory to store a picture taken, or reports an error
	 * Stores the photo under "Photos Taken" in tour folder, as a timestamp with image prefix & suffix
	 */
	private File getAlbumDir() {
		File storageDir = null;
		if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
			File[] tourlist = getBaseContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).listFiles();
			File tour = null;

			for(int i = 0; i < tourlist.length; i++) {
				if(tourlist[i].getName().equals(TourOverview.TOUR_NAME)) {
					tour = tourlist[i];
				}
			}
			storageDir = new File(tour, "Photos Taken");
			if (storageDir != null) {
				if (! storageDir.mkdirs()) {
					if (! storageDir.exists()){
						Toast.makeText(this, "Directory does not exist.", Toast.LENGTH_SHORT).show();
						return null;
					}
				}
			}    
		} 
		else {
			Toast.makeText(this, "External storage is not mounted READ/WRITE.", Toast.LENGTH_SHORT).show();
			return null;
		}
		return storageDir;
	}

	/**
	 * Adds the picture to the directory 
	 */
	private void galleryAddPic() {
		Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
		File f = new File(mCurrentPhotoPath);
		Uri contentUri = Uri.fromFile(f);
		mediaScanIntent.setData(contentUri);
		this.sendBroadcast(mediaScanIntent);
	}

	/**
	 * Creates place in directories to store the image, and then creates the image file
	 * 
	 * @return: File created to store the image
	 * @throws IOException
	 */
	private File createImageFile() throws IOException {
		// Create an image file name
		long timeStamp = new Date().getTime();
		String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
		File image = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, getAlbumDir());
		mCurrentPhotoPath = image.getAbsolutePath();
		return image;
	}

	/**
	 * 1)Receives from the phone its current orientation
	 * 2)Adjusts accordingly
	 */
	private void setContentBasedOnLayout()	{
		int orientation = getResources().getConfiguration().orientation;
		if (orientation == 1 || orientation == 3) {
			// Portrait
			setContentView(R.layout.initial_site);
		}
		else if (orientation == 0 || orientation == 2) {
			// Landscape
			setContentView(R.layout.site_landscape);
		}            
	}

	/**
	 * This method is the dynamic aspect of the page. Depending on the current site number, it refreshes:
	 * - All views on page
	 * - (general description) left side
	 * - (scrollable media list) right side
	 * - returns number of sites found for this tour (to make decision on next move)
	 */
	private int refreshViews() {

		File[] tourlist = getBaseContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).listFiles();
		File tour = null;

		//Find current tour in downloads
		for(int i = 0; i < tourlist.length; i++) {
			//TODO: grab appropriate tour
			if(tourlist[i].getName().equals(TourOverview.TOUR_NAME)) {
				tour = tourlist[i];
			}
		}
		File[] sites = tour.listFiles();
		File site = null;

		//Find current site in tour
		for(int i = 0; i < sites.length; i++) {
			if(sites[i].getName().equals("site" + SITE_NUM)) {
				site = sites[i];
			}
		}

		int count = 1;
		File desc = null;

		//Find description OR Create media access button
		for(int i = 0; i < site.listFiles().length; i++) {
			//TODO: Retrieve appropriate description file
			if(site.listFiles()[i].getName().endsWith("desc.txt")) {
				desc = site.listFiles()[i];
			}
			else if(site.listFiles()[i].getName().startsWith("media") && !site.listFiles()[i].getName().endsWith(".txt")) {
				View v = mediaHandle(site.listFiles()[i]);
				if(v != null) {
					((ViewGroup) findViewById(R.id.mediaScroll_list)).addView(v);
				}
				count++;
			}
		}

		//The following code sets the (left side) description of the site
		TextView tv = (TextView) findViewById(R.id.description);
		StringBuilder text = new StringBuilder();

		try {
			BufferedReader br = new BufferedReader(new FileReader(desc));
			String line;

			while ((line = br.readLine()) != null) {
				text.append(line);
				text.append('\n');
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		tv.setText(text);
		tv.setGravity(Gravity.CENTER_HORIZONTAL);
		return sites.length;
	}

	/**
	 * This is a private function to handle listing media. This is called multiple times to set up 
	 * the scrollable list of media at the right of the page. 
	 * Current supported file types:
	 * -audio
	 * -image
	 * -video
	 * -text
	 * -html
	 * 
	 * @param mediaF: File found when parsing the site folder. Represents a media file
	 * @return : returns a View to be added to the list of media available
	 */
	@SuppressLint("NewApi")
	public View mediaHandle(File mediaF) {
		LayoutParams lparams = new LayoutParams(170,150);
		if(mediaF.getPath().endsWith(".txt")) {
			TextView tv = new TextView(this);
			StringBuilder text = new StringBuilder();

			try {
				BufferedReader br = new BufferedReader(new FileReader(mediaF));
				String line;

				while ((line = br.readLine()) != null) {
					text.append(line);
					text.append('\n');
				}
			}
			catch (IOException e) {
				e.printStackTrace();
			}
			tv.setText(text);
			tv.setGravity(Gravity.CENTER_HORIZONTAL);
			return tv;
		}
		else if(mediaF.getPath().endsWith(".jpg") || mediaF.getPath().endsWith(".png") || mediaF.getPath().endsWith(".gif") || mediaF.getPath().endsWith(".bmp") || mediaF.getPath().endsWith(".webp")) {

			ImageView iv = new ImageView(this);
			iv.setLayoutParams(lparams);

			Bitmap d = BitmapFactory.decodeFile(mediaF.getPath());
			iv.setImageBitmap(d);
			iv.setCropToPadding(true);
			iv.setTag(mediaF.getPath());
			iv.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					Intent intent = new Intent(getBaseContext(), ViewImg.class);
					intent.putExtra(getPackageName(), (String) v.getTag());
					startActivity(intent);
				}
			});
			return iv;
		}
		else if(mediaF.getPath().endsWith(".mp4") || mediaF.getPath().endsWith(".3gp") || mediaF.getPath().endsWith(".webm")) {
			ImageButton ib = new ImageButton(this);
			ib.setLayoutParams(lparams);

			Bitmap bm = ThumbnailUtils.createVideoThumbnail(mediaF.getPath(), MediaStore.Images.Thumbnails.MINI_KIND);
			ib.setImageBitmap(bm);
			ib.setCropToPadding(true);
			ib.setTag(mediaF.getPath());
			ib.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					Intent intent = new Intent(getBaseContext(), PlayVid.class);
					intent.putExtra(getPackageName(), (String) v.getTag());
					startActivity(intent);
				}
			});
			return ib;
		}
		else if(mediaF.getPath().endsWith(".mp3")) {
			LayoutParams l = new LayoutParams(170, 75);

			Button b = new Button(this);
			b.setLayoutParams(l);

			b.setTag(mediaF.getPath());
			b.setText("Audio");
			b.setTextSize(8);
			Drawable d = getResources().getDrawable(R.drawable.headphones);
			d.setBounds(0,0, 32, 32);
			b.setCompoundDrawables(d, null, null, null);

			b.setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					File f = new File((String) v.getTag());
					audioURI = Uri.fromFile(f);

					if(audioView.isPlaying()) {
						audioView.stopPlayback();
					}
					audioView = null;
					audioView =  (VideoView) findViewById(R.id.audioHandle);

					mc.setAnchorView(audioView);

					audioView.setVideoURI(audioURI);
					audioView.setMediaController(mc);
					audioView.start();
					mc.show();
				}
			});
			return b;
		}
		else if(mediaF.getPath().endsWith(".html")) {
			//TODO: Setup image button to view page
			return null;
		}
		else {
			Log.d(TourOverview.TOUR_NAME, "Unsupported file type");
			return null;
		}
	}
}